/*
 * 作者：坚果派
 * 公众号：nutpi
 * 电话：17752170152
 * 官网：https://www.nutpi.net/
 */

import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:shared_preferences/shared_preferences.dart';
import '../models/address_model.dart';
import '../constants/config.dart';

class AddressService {
  static const String _cacheKeyPrefix = 'address_cache_';
  static const String _timestampKeyPrefix = 'address_timestamp_';
  static const Duration _cacheDuration = Duration(days: 30);

  Future<bool> _shouldRefreshCache(String key) async {
    final prefs = await SharedPreferences.getInstance();
    final timestamp = prefs.getInt('${_timestampKeyPrefix}$key');
    if (timestamp == null) return true;
    
    final lastCacheTime = DateTime.fromMillisecondsSinceEpoch(timestamp);
    final now = DateTime.now();
    return now.difference(lastCacheTime) > _cacheDuration;
  }

  Future<void> _saveToCache(String key, String data) async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.setString('${_cacheKeyPrefix}$key', data);
    await prefs.setInt('${_timestampKeyPrefix}$key', DateTime.now().millisecondsSinceEpoch);
  }

  Future<String?> _getFromCache(String key) async {
    final prefs = await SharedPreferences.getInstance();
    return prefs.getString('${_cacheKeyPrefix}$key');
  }

  // 构建带有认证参数的URL
  String _buildUrl(String endpoint, Map<String, String> params) {
    final queryParams = {
      ...params,
      'app_id': appId,
      'app_secret': appSecret,
    };
    final queryString = queryParams.entries
        .map((e) => '${e.key}=${Uri.encodeComponent(e.value)}')
        .join('&');
    return '$baseUrl$endpoint?$queryString';
  }

  // 获取全国城市列表
  Future<List<Province>> getProvinceList() async {
    const cacheKey = 'province_list';
    
    if (!await _shouldRefreshCache(cacheKey)) {
      final cachedData = await _getFromCache(cacheKey);
      if (cachedData != null) {
        final jsonData = json.decode(cachedData);
        final apiResponse = ApiResponse<List<dynamic>>.fromJson(
          jsonData,
          (data) => data as List<dynamic>,
        );
        return apiResponse.data
            .map((item) => Province.fromJson(item))
            .toList();
      }
    }

    final url = _buildUrl('/list', {});
    final response = await http.get(Uri.parse(url));
    
    if (response.statusCode == 200) {
      final jsonData = json.decode(response.body);
      final apiResponse = ApiResponse<List<dynamic>>.fromJson(
        jsonData,
        (data) => data as List<dynamic>,
      );
      
      if (apiResponse.code == 1) {
        await _saveToCache(cacheKey, response.body);
        return apiResponse.data
            .map((item) => Province.fromJson(item))
            .toList();
      } else {
        throw Exception(apiResponse.msg);
      }
    } else {
      throw Exception('Failed to load province list');
    }
  }

  // 搜索全国城市列表
  Future<List<Province>> searchAddress(int type, String value) async {
    final url = _buildUrl('/search', {
      'type': type.toString(),
      'value': value,
    });
    final response = await http.get(Uri.parse(url));
    
    if (response.statusCode == 200) {
      final jsonData = json.decode(response.body);
      final apiResponse = ApiResponse<List<dynamic>>.fromJson(
        jsonData,
        (data) => data as List<dynamic>,
      );
      
      if (apiResponse.code == 1) {
        return apiResponse.data
            .map((item) => Province.fromJson(item))
            .toList();
      } else {
        throw Exception(apiResponse.msg);
      }
    } else {
      throw Exception('Failed to search address');
    }
  }

  // 获取世界级国家城市列表
  Future<List<Country>> getWorldCountryList() async {
    const cacheKey = 'world_country_list';
    
    if (!await _shouldRefreshCache(cacheKey)) {
      final cachedData = await _getFromCache(cacheKey);
      if (cachedData != null) {
        final jsonData = json.decode(cachedData);
        final apiResponse = ApiResponse<List<dynamic>>.fromJson(
          jsonData,
          (data) => data as List<dynamic>,
        );
        return apiResponse.data
            .map((item) => Country.fromJson(item))
            .toList();
      }
    }

    final url = _buildUrl('/v2/list', {});
    final response = await http.get(Uri.parse(url));
    
    if (response.statusCode == 200) {
      final jsonData = json.decode(response.body);
      final apiResponse = ApiResponse<List<dynamic>>.fromJson(
        jsonData,
        (data) => data as List<dynamic>,
      );
      
      if (apiResponse.code == 1) {
        await _saveToCache(cacheKey, response.body);
        return apiResponse.data
            .map((item) => Country.fromJson(item))
            .toList();
      } else {
        throw Exception(apiResponse.msg);
      }
    } else {
      throw Exception('Failed to load world country list');
    }
  }

  // 获取全国城市信息-省份列表
  Future<List<ProvinceSimple>> getProvinceSimpleList() async {
    final url = _buildUrl('/v3/list/province', {});
    final response = await http.get(Uri.parse(url));
    
    if (response.statusCode == 200) {
      final jsonData = json.decode(response.body);
      final apiResponse = ApiResponse<List<dynamic>>.fromJson(
        jsonData,
        (data) => data as List<dynamic>,
      );
      
      if (apiResponse.code == 1) {
        return apiResponse.data
            .map((item) => ProvinceSimple.fromJson(item))
            .toList();
      } else {
        throw Exception(apiResponse.msg);
      }
    } else {
      throw Exception('Failed to load province simple list');
    }
  }

  // 获取全国城市信息-市列表
  Future<List<CitySimple>> getCityList(String provinceCode) async {
    final url = _buildUrl('/v3/list/city', {
      'provinceCode': provinceCode,
    });
    final response = await http.get(Uri.parse(url));
    
    if (response.statusCode == 200) {
      final jsonData = json.decode(response.body);
      final apiResponse = ApiResponse<List<dynamic>>.fromJson(
        jsonData,
        (data) => data as List<dynamic>,
      );
      
      if (apiResponse.code == 1) {
        return apiResponse.data
            .map((item) => CitySimple.fromJson(item))
            .toList();
      } else {
        throw Exception(apiResponse.msg);
      }
    } else {
      throw Exception('Failed to load city list');
    }
  }

  // 获取全国城市信息-区列表
  Future<List<AreaSimple>> getAreaList(String provinceCode, String cityCode) async {
    final url = _buildUrl('/v3/list/area', {
      'provinceCode': provinceCode,
      'cityCode': cityCode,
    });
    final response = await http.get(Uri.parse(url));
    
    if (response.statusCode == 200) {
      final jsonData = json.decode(response.body);
      final apiResponse = ApiResponse<List<dynamic>>.fromJson(
        jsonData,
        (data) => data as List<dynamic>,
      );
      
      if (apiResponse.code == 1) {
        return apiResponse.data
            .map((item) => AreaSimple.fromJson(item))
            .toList();
      } else {
        throw Exception(apiResponse.msg);
      }
    } else {
      throw Exception('Failed to load area list');
    }
  }

  // 获取全国城市信息-街道列表
  Future<List<StreetSimple>> getStreetList(
      String provinceCode, String cityCode, String areaCode) async {
    final url = _buildUrl('/v3/list/street', {
      'provinceCode': provinceCode,
      'cityCode': cityCode,
      'areaCode': areaCode,
    });
    final response = await http.get(Uri.parse(url));
    
    if (response.statusCode == 200) {
      final jsonData = json.decode(response.body);
      final apiResponse = ApiResponse<List<dynamic>>.fromJson(
        jsonData,
        (data) => data as List<dynamic>,
      );
      
      if (apiResponse.code == 1) {
        return apiResponse.data
            .map((item) => StreetSimple.fromJson(item))
            .toList();
      } else {
        throw Exception(apiResponse.msg);
      }
    } else {
      throw Exception('Failed to load street list');
    }
  }

  // 获取全国城市信息-村委会列表
  Future<List<VillageSimple>> getVillageList(
      String provinceCode, String cityCode, String areaCode, String streetCode) async {
    final url = _buildUrl('/v3/list/village', {
      'provinceCode': provinceCode,
      'cityCode': cityCode,
      'areaCode': areaCode,
      'streetCode': streetCode,
    });
    final response = await http.get(Uri.parse(url));
    
    if (response.statusCode == 200) {
      final jsonData = json.decode(response.body);
      final apiResponse = ApiResponse<List<dynamic>>.fromJson(
        jsonData,
        (data) => data as List<dynamic>,
      );
      
      if (apiResponse.code == 1) {
        return apiResponse.data
            .map((item) => VillageSimple.fromJson(item))
            .toList();
      } else {
        throw Exception(apiResponse.msg);
      }
    } else {
      throw Exception('Failed to load village list');
    }
  }
}